home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / INTERRUP.SWG / 0020_Protected Mode Interrupts.pas < prev   
Pascal/Delphi Source File  |  1995-03-03  |  5KB  |  150 lines

  1. {
  2. > One part of the program I am writing must call an interrupt (6A I believe
  3. > - it is a networking interrupt).  The interrupt expects ds:dx to point to a
  4. > structure I have to create.  I know my procedures work because I have
  5. > tested them in real mode.  The problem comes when Is witch into protected
  6. > mode.  The interrupt can no longer find the record that I create. How can I
  7. > do this without too much trouble?  I was thinking of using a known segment,
  8. > such as SegB000 (which I am not using right now), and using memcpy to
  9. > copy the record I create to that segment.  Then I could just point ds:
  10. > SegB000 and dx: 0 and do my interrupt.
  11.  
  12. Here's the unit I use to solve such problems. What you need to do :
  13. - allocate memory in the first megabyte, using AllocateLowMem,
  14. - properly set-up your structure in this memory area, using ProtectedPtr,
  15. - set-up a TRealModeRegs, DS being initialized with the RealSegment of
  16.   the previously allocated memory block,
  17. - call your interrupt with RealModeInt.
  18.  
  19. From: zlika@chaos2.frmug.fr.net (Raphael Vanney)
  20. }
  21.  
  22. { Outils DPMI }
  23. {$x+,g+}
  24.  
  25. {$IfNDef DPMI}
  26.      You don't need that unit.
  27. {$EndIf}
  28.  
  29. Unit MinDPMI ;
  30.  
  31. Interface
  32.  
  33. Type TRealModeRegs =
  34.      Record
  35.           Case Integer Of
  36.           0: ( EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;
  37.                Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word) ;
  38.           1: ( DI,DIH, SI, SIH, BP, BPH, XX, XXH: Word;
  39.                Case Integer of
  40.                  0: (BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);
  41.                  1: (BL, BH, BLH, BHH, DL, DH, DLH, DHH,
  42.                      CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));
  43.      End ;
  44.  
  45.      TLowMemoryBlock     =
  46.      { TLowMemoryBlock is used to point to a memory area within the
  47.        first megabyte, which can thus be accessed both in protected
  48.        and real mode. }
  49.      Record
  50.           ProtectedPtr   : Pointer ;    { pointer valid in protected mode }
  51.           RealSegment    : Word ;       { segment valid in real mode (ofs=0) }
  52.           Size           : Word ;       { size of allocated memory area }
  53.      End ;
  54.  
  55. Procedure ClearRegs(Var RealRegs : TRealModeRegs) ;
  56.  
  57. Function RealModeInt(    IntNo          : Byte ;
  58.                          Var RealRegs   : TRealModeRegs) : Boolean ;
  59. { Important notes :
  60.   . If SS and SP are set to 0, the DPMI server will provide a 30 bytes stack.
  61.   . Calling ClearRegs before initializing registers used for a RealModeInt
  62.     sets SS ans SP to 0.
  63.   }
  64.  
  65. Procedure AllocateLowMem(Var Pt : TLowMemoryBlock ; Size : Word) ;
  66. Procedure FreeLowMem(Var Pt : TLowMemoryBlock) ;
  67.  
  68. Procedure SetProtectedIntVec(No : Byte ; p : Pointer) ;
  69. Procedure GetProtectedIntVec(No : Byte ; Var p : Pointer) ;
  70.  
  71. Implementation
  72.  
  73. Uses WinAPI ;
  74.  
  75. Type TDouble   =
  76.      Record
  77.           Lo, Hi    : Word ;
  78.      End ;
  79.  
  80. Procedure ClearRegs ;
  81. Begin
  82.      FillChar(RealRegs, SizeOf(RealRegs), 0) ;
  83. End ;
  84.  
  85. Function RealModeInt(    IntNo          : Byte ;
  86.                          Var RealRegs   : TRealModeRegs) : Boolean ;
  87. Assembler ;
  88. Asm
  89.      Mov  AX, $0300
  90.      Mov  BL, IntNo
  91.      XOr  BH, BH
  92.      XOr  CX, CX
  93.      LES  DI, RealRegs
  94.      Int  $31
  95.      Mov  AX, 0               { don't use XOr }
  96.      JNC  @Ok
  97.      Inc  AX
  98. @Ok:
  99.      Or   AX, AX
  100. End ;
  101.  
  102. Procedure AllocateLowMem ;
  103. Var  Adr  : LongInt ;
  104. Begin
  105.      Adr:=GlobalDOSAlloc(Size) ;
  106.      If Adr=0 Then Size:=0 ;
  107.      Pt.ProtectedPtr:=Ptr(TDouble(Adr).Lo, 0) ;
  108.      Pt.RealSegment:=TDouble(Adr).Hi ;
  109.      Pt.Size:=Size ;
  110. End ;
  111.  
  112. Procedure FreeLowMem ;
  113. Begin
  114.      GlobalDOSFree(Seg(Pt.ProtectedPtr^)) ;
  115.      FillChar(Pt, SizeOf(Pt), 0) ;           { Fills with NIL }
  116. End ;
  117.  
  118. Procedure SetProtectedIntVec(No : Byte ; p : Pointer) ; Assembler ;
  119. Asm
  120.      Mov  AX, $0205
  121.      Mov  BL, No
  122.      Mov  CX, TDouble[p].Hi        { Selector }
  123.      Mov  DX, TDouble[p].Lo        { Offset }
  124.      Int  $31
  125. End ;
  126.  
  127. Procedure GetProtectedIntVec(No : Byte ; Var p : Pointer) ; Assembler ;
  128. Asm
  129.      Mov  AX, $0204
  130.      Mov  BL, No
  131.      Int  $31
  132.      LES  DI, p
  133.      { Mov  ES:[DI], DX }
  134.      { Mov  ES:[DI+2], CX }
  135.      Mov  TDouble[ES:DI].Lo, DX
  136.      Mov  TDouble[ES:DI].Hi, CX
  137. End ;
  138.  
  139. Function  HugeAdr(Slct : Word ; Ofst : LongInt) : Pointer ;
  140. Assembler ;
  141. Asm
  142.      Mov  AX, SelectorInc
  143.      Mul  TDouble[Ofst].Hi
  144.      Add  AX, Slct                 { First selector of bloc }
  145.      Mov  DX, AX                   { New selector }
  146.      Mov  AX, TDouble[Ofst].Lo     { Low word of offset is the same }
  147. End ;
  148.  
  149. End.
  150.